package com.yyfax.pay.order.controller.api;

import java.util.ArrayList;
import java.util.List;

import javax.validation.Valid;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.yyfax.framework.exception.YYException;
import com.yyfax.framework.model.YYFaxRsp;
import com.yyfax.framework.yyfax.enums.RspCodeEnum;
import com.yyfax.pay.common.annotation.CheckSign;
import com.yyfax.pay.common.enums.PayRspCodeEnum;
import com.yyfax.pay.common.model.to.YYPayApiReq;
import com.yyfax.pay.config.data.service.MerchantConfigService;
import com.yyfax.pay.order.model.po.PayinOrderLogPO;
import com.yyfax.pay.order.model.to.payin.PayinBatchOrderContent;
import com.yyfax.pay.order.model.to.payin.PayinBatchSnapshotVo;
import com.yyfax.pay.order.model.to.payin.PayinOrderBatchParams;
import com.yyfax.pay.order.model.to.payin.PayinOrderContent;
import com.yyfax.pay.order.model.to.payin.PayinOrderParams;
import com.yyfax.pay.order.model.to.payin.PayinOrderVO;
import com.yyfax.pay.order.model.to.payin.PayinSnapshotVo;
import com.yyfax.pay.order.model.to.payin.QueryPayinBatchOrderContent;
import com.yyfax.pay.order.model.to.payin.QueryPayinBatchOrderContent.QueryPayinOrder;
import com.yyfax.pay.order.model.to.payin.QueryPayinBatchOrderParams;
import com.yyfax.pay.order.model.to.payin.QueryPayinOrderContent;
import com.yyfax.pay.order.model.to.payin.QueryPayinOrderParams;
import com.yyfax.pay.order.service.PayinBatchService;
import com.yyfax.pay.order.service.PayinService;

/**
 * 代扣api入口
 * @author maojian
 * @date 2017-04-25
 * @since V1.0.0
 */
@RestController
public class PayinApiController {
	
	private Logger logger = LoggerFactory.getLogger(getClass());

	@Autowired
	private MerchantConfigService merchantConfigService;
	
	@Autowired
	private PayinBatchService payinBatchService;
	
	@Autowired
	private PayinService payinService;
	
	/**
	 * 代扣下单入口
	 * 
	 * @author maojian
	 * @date 2017-05-3 09:04:14
	 * @since v1.0.0
	 * @param sign
	 * @param params
	 * @return
	 * @throws Throwable
	 */
	@RequestMapping(method = RequestMethod.POST, path = "/api/payin/order")
	@CheckSign
	public YYFaxRsp<PayinOrderContent> payinOrder(@RequestBody @Valid YYPayApiReq<PayinOrderParams> req) throws Throwable {
		logger.debug("enter payin order ……");

		PayinOrderContent content = new PayinOrderContent();
		// 1. 持久化代付订单
		PayinSnapshotVo payinSnapshot = payinService.savePayinOrder(req.getParams());
		// 2. 根据快照判断订单是否继续支付
		if(null != payinSnapshot.getOrderLastResultStep() && !PayRspCodeEnum.PAY_CODE_REQ_TIME_OUT.isValue(payinSnapshot.getOrderLastResultStep().getResultCode())){
			BeanUtils.copyProperties(payinSnapshot.getOrderLastResultStep(), content);
			return new YYFaxRsp<PayinOrderContent>(PayRspCodeEnum.SUCCESS, content);
		}
		// 3. 调用支付通道支付返回结果
		content = payinService.payin(payinSnapshot);

		return new YYFaxRsp<PayinOrderContent>(PayRspCodeEnum.SUCCESS, content);
	}
	
	/**
	 * 查询订单状态
	 * 
	 * @author maojian
	 * @date 2017-05-3 18:00:28
	 * @since v1.0.0
	 * @param params
	 * @return
	 * @throws Throwable
	 */
	@RequestMapping(method = RequestMethod.POST, path = "/api/payin/query")
	public YYFaxRsp<QueryPayinOrderContent> payinOrderQuery(@RequestBody @Valid YYPayApiReq<QueryPayinOrderParams> req) throws Throwable {
		logger.debug("enter payin query order ……");

		QueryPayinOrderContent content = new QueryPayinOrderContent();
		QueryPayinOrderParams param = req.getParams();

		PayinSnapshotVo payinSnapshotVo = payinService.queryPayinOrder(param.getOrderId(), param.getMerchantCode());
		if(null == payinSnapshotVo){ // 订单不存在
			content.setResultCode(PayRspCodeEnum.PAY_CODE_QUERY_ORDER_FAIL.getValue());
			content.setResultMsg("订单不存在");
		}else{
			BeanUtils.copyProperties(payinSnapshotVo, content);
	
			PayinOrderLogPO resultStep = payinSnapshotVo.getOrderLastResultStep();
			if (resultStep != null) {
				BeanUtils.copyProperties(resultStep, content);
			} else {
				content.setResultCode(PayRspCodeEnum.PAY_CODE_QUERY_ORDER_FAIL.getValue());
				content.setResultMsg("查询订单结果失败,未找到响应支付结果");
			}
		}

		return new YYFaxRsp<QueryPayinOrderContent>(PayRspCodeEnum.SUCCESS, content);
	}
	
	/**
	 * 批量代扣下单入口
	 * 
	 * @author maojian
	 * @date 2017-04-25
	 * @since v1.0.0
	 * @param sign
	 * @param params
	 * @return
	 * @throws Throwable
	 */
	@RequestMapping(method = RequestMethod.POST, path = "/api/payin/batch/order")
	@CheckSign
	public YYFaxRsp<PayinBatchOrderContent> payinBatchOrder(@RequestBody @Valid YYPayApiReq<PayinOrderBatchParams> req) throws Throwable {
		logger.debug("enter payin order ……");

		PayinBatchOrderContent content = null;
		
		if (req == null || req.getParams() == null) {
			throw new YYException(RspCodeEnum.COMMON_ERROR_PARAMETER_INVALID);
		}

		PayinOrderBatchParams params = req.getParams();

		// 3. 持久化代付订单
		PayinBatchSnapshotVo payinOrder = payinBatchService.saveBatchPayinOrder(params);
		// 3.1  根据快照判断订单是否继续支付
		if(null != payinOrder.getOrderLastResultStep() && !PayRspCodeEnum.PAY_CODE_REQ_TIME_OUT.isValue(payinOrder.getOrderLastResultStep().getResultCode())){
			content = new PayinBatchOrderContent();
			content.setResultCode(payinOrder.getOrderLastResultStep().getResultCode());
			content.setResultMsg(payinOrder.getOrderLastResultStep().getResultMsg());
			content.setMerchantCode(payinOrder.getOrderLastResultStep().getMerchantCode()); // 商户编号
			content.setPaymentCode(payinOrder.getOrderLastResultStep().getPaymentCode());
			content.setOrderId(payinOrder.getOrderLastResultStep().getOrderId()); // 商户订单号
			content.setBatchDate(payinOrder.getOrderLastResultStep().getBatchDate()); // 批次日期
			content.setBatchNo(payinOrder.getOrderLastResultStep().getBatchNo()); // 批次号
			content.setCount(params.getCount()); // 总笔数
			content.setAmount(params.getAmount()); // 总金额
			return new YYFaxRsp<PayinBatchOrderContent>(PayRspCodeEnum.SUCCESS, content);
		}

		// 4. 批量代扣
		content = payinBatchService.payinBatch(payinOrder);

		return new YYFaxRsp<PayinBatchOrderContent>(PayRspCodeEnum.SUCCESS, content);
	}
	
	

	
	/**
	 * 批量代付查询
	 * 
	 * @author maojian
	 * @date 2017-05-3 18:00:28
	 * @since v1.0.0
	 * @param req
	 * @return
	 * @throws Throwable
	 */
	@RequestMapping(method = RequestMethod.POST, path = "/api/payin/batch/query")
	@CheckSign
	public YYFaxRsp<QueryPayinBatchOrderContent> payinBatchQuery(@RequestBody YYPayApiReq<QueryPayinBatchOrderParams> req) throws Throwable {
		logger.debug("enter payin batch order ……");

		if (req == null || req.getParams() == null) {
			throw new YYException(RspCodeEnum.COMMON_ERROR_PARAMETER_INVALID);
		}

		QueryPayinBatchOrderParams params = req.getParams();

		PayinBatchSnapshotVo payinBatchOrderVO = payinBatchService.queryPayinBatchOrder(params.getOrderId(), params.getMerchantCode());

		QueryPayinBatchOrderContent content = new QueryPayinBatchOrderContent();
		BeanUtils.copyProperties(payinBatchOrderVO, content);
		List<QueryPayinOrder> dataList = new ArrayList<QueryPayinOrder>();

		// 转换成响应参数
		List<PayinOrderVO> payinOrderVOs = payinBatchOrderVO.getPayinOrderVOs();
		if (payinOrderVOs != null) {
			for (PayinOrderVO payinOrderVO : payinOrderVOs) {
				QueryPayinOrder queryPayinOrder = new QueryPayinOrder();
				BeanUtils.copyProperties(payinOrderVO, queryPayinOrder);

				dataList.add(queryPayinOrder);
			}
		}
		content.setDataList(dataList);
		return new YYFaxRsp<QueryPayinBatchOrderContent>(PayRspCodeEnum.SUCCESS, content);
	}
}
